require 'rubygems'
require 'metaid'
require 'serverside'

# This can be mixed into any class to make it routable.
module Routable
  # Routes a request.
  def route(req)
    if leaf = find_leaf(req, req.uri)
      leaf.render(req)
    else
      raise "Invalid route (#{req.uri})"
    end
  end
  
  # Finds a leaf recursively.
  def find_leaf(req, path)
    if path =~ /^\/([^\/]+)(.*)$/
      leaf = child_leaf(req, $1.to_sym).find_leaf(req, $2)
    else
      self
    end
  rescue
    nil
  end

  # stock implementation. Finds a child leaf by name (name should be a symbol)
  def child_leaf(request, name)
    @child_leaves ? @child_leaves[name] : nil
  end
  
  # stock implementation. Returns a hash of all child leaves.
  def child_leaves
    @child_leaves || {}
  end
  
  # stock implementation. Adds a child leaf.
  def add_leaf(name, leaf)
    @child_leaves ||= {}
    @child_leaves[name] = leaf
  end
end

class Leaf
  include Routable
  
  def initialize(&block)
    if block
      meta_def(:render, &block)
    end
  end
  
  def render(req)
    req.send_representation(200, 'text/html', "<p>#{req.uri}</p>")
  end
end

server = ServerSide::HTTP::Server.new do
  $root = Leaf.new
  
  def handle
    $root.route(self)
  end
end

l = Leaf.new do |req|
  req.send_representation(200, 'text/html', 'this is abc')
end

$root.add_leaf(:abc, l)

trap('INT') {exit}
puts "Serving on port 8000..."
server.start('0.0.0.0', 8000)